package cn.zwy.day2;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class AddMethodAdapter extends ClassVisitor {

    /**
     * 是否接口
     */
    private boolean isInterface;

    /**
     * 方法是否存在
     */
    private boolean isMethodPresent;

    public AddMethodAdapter(ClassVisitor cw) {
        super(Opcodes.ASM6, cw);
    }

    @Override
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        super.visit(version, access, name, signature, superName, interfaces);
        isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
    }

    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        if (name.equals("toJsonString") && desc.equals("()Ljava/lang/String;")) {
            isMethodPresent = true;
        }
        // 删除方法
        if (name.equals("removeMethod")) {
            // do not delegate to next visitor -> this removes the field
            return null;
        }
        return cv.visitMethod(access, name, desc, signature, exceptions);
    }

    public void visitEnd() {
        if (!isMethodPresent && !isInterface) {
            MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "toJsonString", "()Ljava/lang/String;", null, null);
            mv.visitCode();
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitInsn(Opcodes.ARETURN);
            mv.visitMaxs(1, 1);
            mv.visitEnd();
        }
        cv.visitEnd();
    }

}
